package cn.liumouren.tool.security.autoconfigure.aspect;

import cn.liumouren.tool.security.autoconfigure.annotation.RequirePermissions;
import cn.liumouren.tool.security.autoconfigure.exception.PermissionDeniedException;
import cn.liumouren.tool.security.autoconfigure.util.CollectionUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author Daniel Liu
 * @date 2021/3/5 15:40
 */
@Aspect
@Component
public class PermissionAspect {

    @Pointcut("@annotation(cn.liumouren.tool.security.autoconfigure.annotation.RequirePermissions)")
    public void methodWithPermissionAnnotation() {
    }

    @Before("methodWithPermissionAnnotation()")
    public void before(JoinPoint joinPoint) throws Exception {
        RequirePermissions requirePermissions = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(RequirePermissions.class);
        if (requirePermissions != null) {
            String[] needPermissions = requirePermissions.value();
//            List<String> curPermissions = tokenProcessor.parse(getToken()).get();
            cn.liumouren.tool.security.core.Permission role = (cn.liumouren.tool.security.core.Permission) getRequest().getAttribute("permission");
            List<String> curPermissions = role.get();
            if (!CollectionUtil.containsAll(curPermissions, Arrays.asList(needPermissions))) {
                throw new PermissionDeniedException("insufficient permissions!");
            }
        }
    }

//    private String getToken() {
//        String header = properties.getTokenHeader();
//        String prefix = properties.getPrefix();
//        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(
//                RequestContextHolder.getRequestAttributes()))
//                .getRequest();
//        String token = request.getHeader(header);
//        if (token != null && token.startsWith(prefix)) {
//            return token.replace(prefix, "");
//        }
//        throw new TokenFormatException("illegal token!");
//    }

    private HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(
                RequestContextHolder.getRequestAttributes()))
                .getRequest();
    }


}
